import React, {Component} from 'react'
import _ from 'underscore'

import View from 'lib/View.jsx'
import DefaultLoadingElement from 'lib/util/defaultLoadingElement.jsx'
import DefaultNoDataElement from 'lib/util/defaultNoDataElement.jsx'
import DefaultErrorElement from 'lib/util/defaultErrorElement.jsx'
import formatter from 'lib/util/format'

import SingleInfoCell from './SingleInfoCell.jsx'

export class HealthExaminationCanvas extends Component {
  constructor(props, context) {
    super(props, context);

    let segments = parseInt((100-props.score)/5);
    if (segments === 0) {
      segments = 1;
    }
    if ((100 - props.score) % 5 > 0) {
      segments += 1;
    }
    if (segments === 1) {
      segments += 1;
    }

    let scores = new Array(segments);
    for (let i = 0; i < scores.length; i++) {
      let score = scores[i] = {score:100-5*i};
      if (i === scores.length-1) {
        score.score = props.score;
      }

      if (score.score > 80) {
        score.backgroundColor = '#56BC76';
      } else if (score.score > 60 && score.score <= 80) {
        score.backgroundColor = '#e5c85e';
      } else {
        score.backgroundColor = '#e5603b';
      }
    }

    this.state = {
      index:0,
      isAnimation: false,
      scores,
      delay:parseInt(3000 / segments)
    };
  }

  executeAnimation() {
    if (this.state.index >= this.state.scores.length-1) {
      return;
    }

    this.__timeout = setTimeout(()=>{
      this.__timeout = null;
      this.setState({index:this.state.index+1},()=>this.executeAnimation());
    }, this.state.delay);
  }

  componentDidMount() {
    this.__timeout = setTimeout(()=>{
      this.__timeout = null;
      this.setState({index:1,isAnimation:true},()=>this.executeAnimation());
    }, this.state.delay);
  }

  componentWillUnmount() {
    if (this.__timeout) {
      clearTimeout(this.__timeout);
    }
  }

  renderMain(key, target, mainStyle) {
    return (
      <div key={key} style={_.extend({
        position:'absolute',
        left:'0px',
        top:'0px',
        opacity:0,
        transition:'all '+this.state.delay+'ms ease-in-out',
        height:this.props.diameter+'px',
        width:this.props.diameter+'px'
      },mainStyle)}>
        <div style={{
          position:'absolute',
          top:'0px',
          left:'0px',
          lineHeight:this.props.diameter+'px',
          width:this.props.diameter+'px',
          textAlign:'center'
        }}>
          <span style={{
            fontSize:'40px',
            marginRight:'14px',
            fontFamily:'Arial, Helvetica'
          }}>
            {target.score}
          </span>
        </div>
        <div style={{
          position:'absolute',
          top:'0px',
          left:'0px',
          lineHeight:this.props.diameter+'px',
          width:this.props.diameter+'px',
          textAlign:'center'
        }}>
          <div style={{
            padding:'5px 0px 0px ' + (target.score === 100 ? '72px' : '57px')
          }}>
            分
          </div>
        </div>
      </div>
    );
  } // renderMain

  render() {
    if (!this.state.scores.length) {
      return null;
    }

    return (
      <div style={{
        position:'relative',
        width:this.props.diameter+'px',
        height:this.props.diameter+'px',
        margin:'auto'
      }}>
        <div style={{
          position:'absolute',
          top:'0px',
          left:'0px',
          height:this.props.diameter+'px',
          width:this.props.diameter+'px',
          backgroundColor:this.state.scores[this.state.index].backgroundColor,
          borderRadius:this.props.diameter/2+'px'
        }} />
        {
          !this.state.isAnimation
            ? (
              <div>
              {
                this.renderMain(0, this.state.scores[0], {
                  opacity:1,
                  top:'0px'
                })
              }
              {
                this.renderMain(1,this.state.scores[1],{
                  opacity:0,
                  top:'30px'
                })
              }
              </div>
            ) : (
              <div>
              {
                this.renderMain(this.state.index-1,this.state.scores[this.state.index-1],{
                  opacity:0,
                  top:'-30px'
                })
              }
              {
                this.renderMain(this.state.index,this.state.scores[this.state.index],{
                  opacity:1,
                  top:'0px'
                })
              }
              {
                (this.state.index < this.state.scores.length-1)
                  ? (
                    this.renderMain(this.state.index+1,this.state.scores[this.state.index+1],{
                      opacity:0,
                      top:'30px'
                    })
                  ) : null
              }
              </div>
            )
        }

      </div>
    );
  }
}

HealthExaminationCanvas.defaultProps = {
  diameter:122,
  score:53
}

export class HealthExaminationCanvasStatic extends Component {
  render() {
    return (
      <div style={{
        position:'relative',
        width:this.props.diameter+'px',
        height:this.props.diameter+'px',
        margin:'auto'
      }}>
        <div style={{
          position:'absolute',
          top:'0px',
          left:'0px',
          height:this.props.diameter+'px',
          width:this.props.diameter+'px',
          backgroundColor:'#56BC76',
          borderRadius:this.props.diameter/2+'px'
        }} />
        <div style={{
          position:'absolute',
          left:'0px',
          top:'0px',
          height:this.props.diameter+'px',
          width:this.props.diameter+'px'
        }}>
          <div style={{
            position:'absolute',
            top:'0px',
            left:'0px',
            lineHeight:this.props.diameter+'px',
            width:this.props.diameter+'px',
            textAlign:'center'
          }}>
            <span style={{
              fontSize:'40px',
              fontFamily:'Arial, Helvetica'
            }}>
              --
            </span>
          </div>
        </div>
      </div>
    );
  }
}

HealthExaminationCanvasStatic.defaultProps = {
  diameter:122
}

export default class HealthExamination extends View {

  constructor(props, context) {
    super(props, context);

    this.state = {
      progressBarWidth:'0px',
      renderTip0:false,
      renderTip1:false,
      renderTip2:false,
      renderTip3:false,

      title:'正在检测中……',
      body:'正在检测各项性能指标，该项内容较多，请耐心等待……'
    };
  }

  millisecondFormatter(value) {
    if (value > 1000*60) {
      return (value / 1000 / 60).toFixed(2);
    } else if (value > 1000) {
      return (value / 1000).toFixed(2);
    } else {
      return value.toFixed(0);
    }
  }

  millisecondUnitFormatter(value) {
    if (value > 1000*60) {
      return 'min';
    } else if (value > 1000) {
      return 's';
    } else {
      return 'ms';
    }
  }

  rate(value) {
    return (value * 100).toFixed(2);
  }

  kSize(v) {
    if (v !== 0 && !v) {
      return '0';
    }

    var bits = (v).toString().replace(/\.\d+/,'').length;
    var units = ['','K','M','G','T','P','E','Z','Y'];
    var i;
    for(i=units.length-1;i>0;i--){
      if(bits>i*3){
        return formatter.numberic(v / Math.pow(10,i*3)) + ' '+units[i]
      }
    }
    return Math.round(v);
  }

  kSizeValue(v) {
    if (v !== 0 && !v) {
      return '0';
    }

    var bits = (v).toString().replace(/\.\d+/,'').length;
    var units = ['','K','M','G','T','P','E','Z','Y'];
    var i;
    for(i=units.length-1;i>0;i--){
      if(bits>i*3){
        return formatter.numberic(v / Math.pow(10,i*3))
      }
    }
    return v;
  }

  kSizeUnit(v) {
    if (v !== 0 && !v) {
      return '';
    }

    var bits = (v).toString().replace(/\.\d+/,'').length;
    var units = ['','K','M','G','T','P','E','Z','Y'];
    var i;
    for(i=units.length-1;i>0;i--){
      if(bits>i*3){
        return units[i]
      }
    }
    return '';
  }

  animateProgressBar() {
    if (this.state.progressBarWidth === '0px' && this.props.store.data) {
      // 设置文本提示信息
      setTimeout(()=>this.setState({
        title:this.props.store.data.judgement.title,
        body:this.props.store.data.judgement.meaning
      }), 3000);

      // 呈现动画效果必要的延迟
      this.__timeout = setTimeout(()=>this.setState({progressBarWidth:'100%'}), 0);

      // 延迟显示体检下面的四个小 TIP 标签
      if (this.__timeoutTip) {
        clearTimeout(this.__timeoutTip);
      }
      let index = 0;
      let tipFunc = ()=>{
        this.__timeoutTip = null;
        let newState = {};
        newState['renderTip'+index]=true;
        this.setState(newState,()=>{
          index++;
          if (index < 4) {
            this.__timeoutTip = setTimeout(tipFunc, 750);
          }
        });
      };
      this.__timeoutTip = setTimeout(tipFunc, 750);
    }
  }

  componentDidMount() {
    super.componentDidMount();
    if (this.props.store.data && this.props.store.data.judgement.name !== 'unuse') {
      this.animateProgressBar();
    }
  }

  componentDidUpdate(prevProps, prevState) {
    if (this.props.store.data && this.props.store.data.judgement.name !== 'unuse') {
      this.animateProgressBar();
    }
  }

  shouldComponentUpdate(nextProps, nextState) {
    return !this.props.data;
  }

  componentWillUnmount() {
    if (this.__timeout) {
      clearTimeout(this.__timeout);
    }
  }

  renderLoading() {
    return (
      <div key="laoding">
        <div className="pure-g" style={{'margin':'28px auto 11px auto'}}>
          <div className="pure-u-1-4">
            <HealthExaminationCanvasStatic />
          </div>
          <div className="pure-u-3-4">
            <div className="pure-g" style={{marginLeft:'12px'}}>
              <div className="pure-u-1">
                <p style={{'fontWeight':400, 'fontStyle':'normal', 'fontSize':'24px', 'textDecoration':'none', 'color':'#F8F8F8', 'marginBottom':'15px', 'marginTop':'10px'}}>
                  {this.state.title}
                </p>
                <p style={{'fontWeight':400, 'fontStyle':'normal', 'fontSize':'14px', 'textDecoration':'none', 'color':'#F8F8F8', 'marginTop':'5px'}}>
                  {this.state.body}
                </p>
              </div>
            </div>
          </div>
        </div>
        <div className="pure-g">
          <div className="pure-u-1">
            <div style={{height:'1px',backgroundColor:'rgba(192,208,224,0.4)',margin:'15px 0px',width:'100%'}} />
          </div>
        </div>
        <div className="pure-g" style={{marginTop:'11px'}}>
          <div className="pure-u-1" style={{display:'inline-table',textAlign:'center'}}>
            <div style={{display:'table-cell'}}>
              <SingleInfoCell key={1} style={{margin:'auto'}} loading={true} />
            </div>
            <div style={{display:'table-cell'}}>
              <SingleInfoCell key={2} style={{margin:'auto'}} loading={true} />
            </div>
            <div style={{display:'table-cell'}}>
              <SingleInfoCell key={3} style={{margin:'auto'}} loading={true} />
            </div>
            <div style={{display:'table-cell'}}>
              <SingleInfoCell key={4} style={{margin:'auto'}} loading={true} />
            </div>
          </div>
        </div>
      </div>
    );
  }

  renderBody(target) {
    let crashName = '崩溃率'
      , crashUnit = '%'
      , crashFunc = () => this.rate(target.rankings[`rate.crash.${BlueWare.isIOS?'ios':'android'}`]);

    if (BlueWare.isIOS) {
      if (BlueWare.crashRateSupported) {
        crashName = (
          <span>
            崩溃率
            <i className="iconfont crash-count" data-tip="iOS 探针 2.2.0.5 以上支持崩溃率指标">&#xe663;</i>
          </span>
        );
      } else {
        crashName = (
          <span>
            崩溃次数
            <i className="iconfont crash-count" data-tip="iOS 探针 2.2.0.5 以上支持崩溃率指标">&#xe663;</i>
          </span>
        );
        crashUnit = '次';
        crashFunc = () => formatter.integer(target.rankings[`count.${BlueWare.isIOS?'ios':'android'}.crash`]);
      }
    }

    return (
      <div key="body">
        <div className="pure-g" style={{'margin':'28px auto 11px auto'}}>
          <div className="pure-u-1-4">
          {
            target.judgement.name === 'unuse'
              ? <HealthExaminationCanvasStatic />
              : <HealthExaminationCanvas score={target.score} />
          }
          </div>
          <div className="pure-u-3-4">
            <div className="pure-g" style={{marginLeft:'12px'}}>
              <div className="pure-u-1">
                <p style={{'fontWeight':400, 'fontStyle':'normal', 'fontSize':'24px', 'textDecoration':'none', 'color':'#F8F8F8', 'marginBottom':'15px', 'marginTop':'10px'}}>
                  {target.judgement.name === 'unuse'?target.judgement.title:this.state.title}
                </p>
                <p style={{'fontWeight':400, 'fontStyle':'normal', 'fontSize':'14px', 'textDecoration':'none', 'color':'#F8F8F8', 'marginTop':'5px'}}>
                  {target.judgement.name === 'unuse'?target.judgement.meaning:this.state.body}
                </p>
              </div>
            </div>
          </div>
        </div>
        <div className="pure-g">
          <div className="pure-u-1">
            <div
              style={_.extend({
                height:'1px',
                backgroundColor:'rgba(192, 208, 224, 0.4)',
                margin:'15px 0px',
                width:target.judgement.name === 'unuse'?'100%':this.state.progressBarWidth
              },target.judgement.name === 'unuse'?{}:{transition: 'width 3s linear'})} />
          </div>
        </div>
        <div className="pure-g" style={{marginTop:'11px'}}>
          <div className="pure-u-1" style={{display:'inline-table',textAlign:'center'}}>
            <div style={{display:'table-cell'}}>
              <SingleInfoCell
                key={1}
                iconClass="icon-clock"
                style={{margin:'auto'}}
                title="平均执行时间"
                link="interaction"
                value={this.millisecondFormatter(target.rankings['avg.activity.execute.time'])}
                unit={this.millisecondUnitFormatter(target.rankings['avg.activity.execute.time'])}
                desc={'执行次数：'+this.kSize(target.rankings['count.activity.execute'])}
                loading={target.judgement.name === 'unuse'?false:!this.state.renderTip0} />
            </div>
            <div style={{display:'table-cell'}}>
              <SingleInfoCell
                key={2}
                iconClass="icon-bug"
                style={{margin:'auto'}}
                title={crashName}
                link="crashlog"
                value={crashFunc()}
                unit={crashUnit}
                desc={'影响用户数：'+this.kSize(target.rankings['count.'+(BlueWare.isIOS?'ios':'android')+'.crash.affectedUsers'])}
                loading={target.judgement.name === 'unuse'?false:!this.state.renderTip1} />
            </div>
            <div style={{display:'table-cell'}}>
              <SingleInfoCell
                key={3}
                iconClass="icon-console"
                style={{margin:'auto'}}
                title="HTTP错误率"
                link="error"
                value={this.rate(target.rankings['rate.error.http'])}
                unit="%"
                desc={'影响用户数：'+this.kSize(target.rankings['count.http.status.error.affectedUsers'])}
                loading={target.judgement.name === 'unuse'?false:!this.state.renderTip2} />
            </div>
            <div style={{display:'table-cell'}}>
              <SingleInfoCell
                key={4}
                iconClass="icon-net"
                style={{margin:'auto'}}
                title="网络错误率"
                link="error"
                value={this.rate(target.rankings['rate.error.network'])}
                unit="%"
                desc={'影响用户数：'+this.kSize(target.rankings['count.http.net.error.affectedUsers'])}
                loading={target.judgement.name === 'unuse'?false:!this.state.renderTip3} />
            </div>
        </div>
        </div>
      </div>
    );
  }

  render(){
    if(this.props.store.loading){
      return this.renderLoading();
    }else if(this.props.store.error){
      return (<DefaultErrorElement height={this.props.height} style={{marginTop:'28px'}} />);
    }else if(this.props.store.data){
      return this.renderBody(this.props.store.data);
    }else{
      return null;
    }
  }
}

HealthExamination.defaultProps = {
  height:216,
  store:{loading:true}
}
